#ifndef     __SDL_WINDOW_H
#define     __SDL_WINDOW_H

#include <QWidget>
#include <memory.h>
#include "../utils/error.h"
#include <SDL2/SDL.h>
#include "../utils/image.h"


class SDLWindow {

public:
    SDLWindow(QWidget *w) :
        m_window(
            SDL_CreateWindowFrom((void *)w->winId()),
            SDL_DestroyWindow),
        m_renderer(
            SDL_CreateRenderer(
                m_window.get(),
                -1,
                SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
                ),
            SDL_DestroyRenderer),
        m_texture(
            SDL_CreateTexture(
                m_renderer.get(),
                SDL_PIXELFORMAT_YV12,
                SDL_TEXTUREACCESS_STREAMING,
                w->width(), w->height()
                ),
            SDL_DestroyTexture)
    {
        if ((m_window == nullptr) ||
            (m_renderer == nullptr) ||
            (m_texture == nullptr))
        {
            throw SDLException("create");
        }
        width = w->width();
        height = w->height();
    //    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
    //    SDL_RenderSetLogicalSize(m_renderer.get(), w->width(), w->height());
    //    SDL_SetRenderDrawColor(m_renderer.get(), 0, 0, 0, 255);
    //    SDL_RenderClear(m_renderer.get());
    //    SDL_RenderPresent(m_renderer.get());
    }

    void refresh(const Image &image) {
        SDL_RenderClear(m_renderer.get());
        SDL_SetTextureBlendMode(m_texture.get(), SDL_BLENDMODE_BLEND);
        int ec = SDL_UpdateYUVTexture(
            m_texture.get(), nullptr,
            image.pointers[0], image.linesizes[0],
            image.pointers[1], image.linesizes[1],
            image.pointers[2], image.linesizes[2]
            );
        if (ec < 0) {
            throw SDLException("update texture");
        }

        SDL_RenderCopy(m_renderer.get(), m_texture.get(), nullptr, nullptr);
        SDL_RenderPresent(m_renderer.get());
    }

    int width;
    int height;

private:
    std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> m_window;
    std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer *)> m_renderer;
    std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)> m_texture;
};

#endif
